#include "infones_adapter.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>

// 全局状态
static bool g_is_initialized = false;
static bool g_is_running = false;
static bool g_is_paused = false;
static uint8_t g_controller_state[2] = {0, 0};
static uint8_t* g_rom_data = nullptr;
static uint32_t g_rom_size = 0;
static char g_temp_rom_path[256] = "/tmp/temp_rom.nes";

// 显示系统相关全局变量
static void* g_native_window = nullptr;
static ArkGraphics2D* g_graphics = nullptr;
static bool g_display_initialized = false;

// 初始化适配器
bool InfoNES_Adapter_Init(void) {
    if (g_is_initialized) {
        return true;
    }
    
    // 初始化infoNES核心
    InfoNES_Init();
    
    // 初始化音频系统
    InfoNES_SoundInit();
    
    // 初始化显示系统
    InfoNES_Display_Init();
    
    g_is_initialized = true;
    g_is_running = false;
    g_is_paused = false;
    
    return true;
}

// 清理适配器
void InfoNES_Adapter_Deinit(void) {
    if (!g_is_initialized) {
        return;
    }
    
    // 释放ROM数据
    if (g_rom_data) {
        free(g_rom_data);
        g_rom_data = nullptr;
    }
    
    // 释放ROM内存
    InfoNES_ReleaseRom();
    
    // 关闭音频
    InfoNES_SoundClose();
    
    // 清理显示系统
    InfoNES_Display_Fin();
    
    g_is_initialized = false;
    g_is_running = false;
}

// 加载ROM
bool InfoNES_Adapter_LoadROM(const uint8_t* data, uint32_t size) {
    if (!g_is_initialized || !data || size == 0) {
        return false;
    }
    
    // 释放之前的ROM数据
    if (g_rom_data) {
        free(g_rom_data);
    }
    
    // 分配新的ROM数据空间
    g_rom_data = (uint8_t*)malloc(size);
    if (!g_rom_data) {
        return false;
    }
    
    // 复制ROM数据
    memcpy(g_rom_data, data, size);
    g_rom_size = size;
    
    // 写入临时文件（infoNES期望从文件加载）
    FILE* fp = fopen(g_temp_rom_path, "wb");
    if (!fp) {
        free(g_rom_data);
        g_rom_data = nullptr;
        return false;
    }
    
    fwrite(g_rom_data, 1, size, fp);
    fclose(fp);
    
    // 调用infoNES加载ROM
    int result = InfoNES_Load(g_temp_rom_path);
    if (result != 0) {
        free(g_rom_data);
        g_rom_data = nullptr;
        return false;
    }
    
    // 重置系统
    InfoNES_Reset();
    
    g_is_running = true;
    return true;
}

// 重置系统
void InfoNES_Adapter_Reset(void) {
    if (!g_is_initialized) {
        return;
    }
    
    InfoNES_Reset();
}

// 运行一帧
void InfoNES_Adapter_RunFrame(void) {
    if (!g_is_initialized || !g_is_running || g_is_paused) {
        return;
    }
    
    // 运行一帧
    InfoNES_Main();
}

// 设置控制器状态
void InfoNES_Adapter_SetControllerState(int controller, uint8_t state) {
    if (controller >= 0 && controller < 2) {
        g_controller_state[controller] = state;
    }
}

// 获取屏幕缓冲区
uint16_t* InfoNES_Adapter_GetScreenBuffer(void) {
    if (!g_is_initialized) {
        return nullptr;
    }
    
    // 返回infoNES的工作帧缓冲区
    return WorkFrame;
}

// 检查是否正在运行
bool InfoNES_Adapter_IsRunning(void) {
    return g_is_running;
}

// 暂停模拟器
void InfoNES_Adapter_Pause(void) {
    g_is_paused = true;
}

// 恢复模拟器
void InfoNES_Adapter_Resume(void) {
    g_is_paused = false;
}

// 设置Native Window
void InfoNES_Adapter_SetNativeWindow(void* window) {
    InfoNES_Display_SetNativeWindow(window);
}

// ============================================================================
// 系统接口实现
// ============================================================================

int InfoNES_Menu(void) {
    // 在HarmonyOS中，菜单功能可能不需要
    return 0;
}

int InfoNES_ReadRom(const char* pszFileName) {
    // 这个函数由InfoNES_Load调用
    // 我们需要从临时文件中读取ROM数据到infoNES的内存中
    
    if (!g_rom_data || g_rom_size == 0) {
        return -1;
    }
    
    // 解析NES文件头
    if (g_rom_size < sizeof(NesHeader)) {
        return -1;
    }
    
    // 复制文件头
    memcpy(&NesHeader, g_rom_data, sizeof(NesHeader));
    
    // 检查NES文件标识
    if (memcmp(NesHeader.byID, "NES\x1a", 4) != 0) {
        return -1; // 不是.nes文件
    }
    
    // 清除SRAM
    memset(SRAM, 0, SRAM_SIZE);
    
    // 计算数据偏移
    int dataOffset = sizeof(NesHeader);
    
    // 如果有trainer，跳过512字节
    if (NesHeader.byInfo1 & 4) {
        dataOffset += 512;
    }
    
    // 分配PRG ROM内存
    ROM = (BYTE*)malloc(NesHeader.byRomSize * 0x4000);
    if (!ROM) {
        return -1;
    }
    
    // 读取PRG ROM数据
    if (dataOffset + NesHeader.byRomSize * 0x4000 > g_rom_size) {
        free(ROM);
        ROM = NULL;
        return -1;
    }
    
    memcpy(ROM, g_rom_data + dataOffset, NesHeader.byRomSize * 0x4000);
    dataOffset += NesHeader.byRomSize * 0x4000;
    
    // 如果有CHR ROM，分配内存并读取
    if (NesHeader.byVRomSize > 0) {
        VROM = (BYTE*)malloc(NesHeader.byVRomSize * 0x2000);
        if (!VROM) {
            free(ROM);
            ROM = NULL;
            return -1;
        }
        
        if (dataOffset + NesHeader.byVRomSize * 0x2000 > g_rom_size) {
            free(ROM);
            free(VROM);
            ROM = NULL;
            VROM = NULL;
            return -1;
        }
        
        memcpy(VROM, g_rom_data + dataOffset, NesHeader.byVRomSize * 0x2000);
    }
    
    return 0;
}

void InfoNES_ReleaseRom(void) {
    // 释放ROM内存
    if (ROM) {
        free(ROM);
        ROM = NULL;
    }
    
    if (VROM) {
        free(VROM);
        VROM = NULL;
    }
    
    // 释放适配器的ROM数据
    if (g_rom_data) {
        free(g_rom_data);
        g_rom_data = nullptr;
    }
}

void InfoNES_LoadFrame(void) {
    // 在HarmonyOS中，我们使用Native Window和ArkGraphics 2D进行渲染
    if (!g_display_initialized || !g_native_window || !WorkFrame) {
        return;
    }
    
    // 获取Native Window
    NativeWindow* window = (NativeWindow*)g_native_window;
    
    // 创建ArkGraphics 2D画布
    // 注意：这里需要根据实际的HarmonyOS API实现
    // ArkGraphics2D* graphics = CreateArkGraphics2D(window);
    // if (!graphics) {
    //     return;
    // }
    
    // 渲染NES画面
    for (int y = 0; y < NES_DISP_HEIGHT; y++) {
        for (int x = 0; x < NES_DISP_WIDTH; x++) {
            WORD nesColor = WorkFrame[y * NES_DISP_WIDTH + x];
            uint32_t argbColor = InfoNES_ConvertColor(nesColor);
            
            // 使用ArkGraphics 2D绘制像素
            // graphics->DrawPixel(x, y, argbColor);
            
            // 临时实现：直接输出到控制台
            if (x == 0 && y == 0) {
                printf("Rendering frame: %dx%d, first pixel color: 0x%08X\n", 
                       NES_DISP_WIDTH, NES_DISP_HEIGHT, argbColor);
            }
        }
    }
    
    // 提交画面
    // graphics->Flush();
    // ReleaseArkGraphics2D(graphics);
    
    // 临时实现：模拟渲染完成
    printf("Frame rendered successfully\n");
}

void InfoNES_PadState(DWORD* pdwPad1, DWORD* pdwPad2, DWORD* pdwSystem) {
    // 设置控制器状态
    *pdwPad1 = g_controller_state[0];
    *pdwPad2 = g_controller_state[1];
    *pdwSystem = 0; // 系统按键暂时不使用
}

void* InfoNES_MemoryCopy(void* dest, const void* src, int count) {
    return memcpy(dest, src, count);
}

void* InfoNES_MemorySet(void* dest, int c, int count) {
    return memset(dest, c, count);
}

void InfoNES_DebugPrint(char* pszMsg) {
    // 在HarmonyOS中，可以使用日志系统
    printf("InfoNES Debug: %s\n", pszMsg);
}

void InfoNES_Wait(void) {
    // 等待函数，在HarmonyOS中可能不需要
}

void InfoNES_SoundInit(void) {
    // 初始化音频系统
    // 在HarmonyOS中，可以使用音频API
}

int InfoNES_SoundOpen(int samples_per_sync, int sample_rate) {
    // 打开音频设备
    // 在HarmonyOS中，可以使用音频API
    return 0;
}

void InfoNES_SoundClose(void) {
    // 关闭音频设备
    // 在HarmonyOS中，可以使用音频API
}

void InfoNES_SoundOutput(int samples, BYTE* wave1, BYTE* wave2, BYTE* wave3, BYTE* wave4, BYTE* wave5) {
    // 输出音频
    // 在HarmonyOS中，可以使用音频API
}

void InfoNES_MessageBox(char* pszMsg, ...) {
    // 显示消息框
    // 在HarmonyOS中，可以使用对话框API
    printf("InfoNES Message: %s\n", pszMsg);
}

// ============================================================================
// 显示系统实现
// ============================================================================

void InfoNES_Display_Init(void) {
    // 初始化显示系统
    g_display_initialized = false;
    g_native_window = nullptr;
    g_graphics = nullptr;
}

void InfoNES_Display_Fin(void) {
    // 清理显示系统
    if (g_graphics) {
        // ReleaseArkGraphics2D(g_graphics);
        g_graphics = nullptr;
    }
    g_native_window = nullptr;
    g_display_initialized = false;
}

void InfoNES_Display_SetNativeWindow(void* window) {
    g_native_window = window;
    if (window && !g_display_initialized) {
        // 创建ArkGraphics 2D画布
        // g_graphics = CreateArkGraphics2D(window);
        g_display_initialized = true;
    }
}

uint32_t InfoNES_ConvertColor(WORD nesColor) {
    // 将NES的16位颜色转换为32位ARGB格式
    // NES颜色格式: RRRRR GGGGGG BBBBB
    uint8_t r = (nesColor >> 11) & 0x1F;
    uint8_t g = (nesColor >> 5) & 0x3F;
    uint8_t b = nesColor & 0x1F;
    
    // 转换为8位颜色
    r = (r << 3) | (r >> 2);
    g = (g << 2) | (g >> 4);
    b = (b << 3) | (b >> 2);
    
    // 返回ARGB格式 (0xFFRRGGBB)
    return 0xFF000000 | (r << 16) | (g << 8) | b;
}
